
#include "../../Command.h"

#include "../../User.h"
#include "../../NLogic/Space.h"
#include "../../NLogic/Static.h"
#include "../../NLogic/Battle.h"
#include "../../NLogic/SocialInfo.h"
#include "../../NLogic/Stamina.h"
#include "../../NResource/Static.h"

#include "../../Proxy.h"

namespace ProjectZ { namespace NCommand {

static void SendFailDungeonCreatePartyFriendV2(User * pUser, int ack)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	*pAck << static_cast<int16_t>(ack);
	pAck->MakePacket(CMD_SC_REQ_DUNGEON_CREATE_PARTY_FRIEND_V2);
	pUser->Send(pAck);
}

void Command::CS_REQ_DUNGEON_CREATE_PARTY_FRIEND_V2(User * pUser, ::Network::Packet *pPacket)
{
/*	/// 친구와 플레이
	CS_REQ_DUNGEON_CREATE_PARTY_FRIEND_V2       0x1138
	{
	           u16 u16dungeon_tid;                //추가됨
	           u8 u8difficulty;
	           u8 count
	           {
	                     u32      u32gid;                       /// 초대할 유저의 gid
	           }
	}

	SC_REQ_DUNGEON_CREATE_PARTY_FRIEND_V2       0x1139
	{
	           s16       ack;                                      /// 1:완료 , 1400: 전투 후유증, 3400: 스태미너 부족
	           u32      party_seq;                              /// 파티 시퀀스
	}*/


	NLogic::Space * pWorld = pUser->GetSpace();
	if (NULL == pWorld)
	{
		DEBUGLOG("%s : NULL == pWorld", __FUNCTION__);
		SendFailDungeonCreatePartyFriendV2(pUser, ACK_NO_SPACE);
		return;
	}

	if (false == pUser->EndBattle_afterEffect())
	{
		SendFailDungeonCreatePartyFriendV2(pUser, ACK_BATTLE_AFTEREFFECT);
		return;
	}

	if (pUser->GetEnumState() != User::EnumState::__NONE__)
	{
		DEBUGLOG("%s : pUser->GetEnumState() != User::EnumState::__NONE__", __FUNCTION__);
		SendFailDungeonCreatePartyFriendV2(pUser, ACK_UNKNOWN_ERROR);
		return;
	}


	PREPARE_PACKET;

	char count = 0;
	uint16_t dungeon_id = 0;
	uint8_t difficulty = 0;

	*pPacket >> dungeon_id >> difficulty >> count;

	if (difficulty < 0 || difficulty > 2)
	{
		DEBUGLOG("%s : INVALID DIFFICULTY!! difficulty=%d", __FUNCTION__, difficulty);
		SendFailDungeonCreatePartyFriendV2(pUser, ACK_UNKNOWN_ERROR);
	}

	NResource::DungeonData::Flyweight * pFly =
			NResource::Static::InstancePtr()->GetDungeon()->GetFly(pUser->GetCompany(), pUser->GetSaleCode(), dungeon_id);
	if (pFly == NULL)
	{
		DEBUGLOG("%s : pFly == NULL! dungeon_id=%d", __FUNCTION__, dungeon_id);
		SendFailDungeonCreatePartyFriendV2(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	if (count > 4 || count <= 0)
	{
		DEBUGLOG("%s : count > 4 || count <= 0 count : %d", __FUNCTION__, static_cast<int>(count));
		SendFailDungeonCreatePartyFriendV2(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	// 스태미너 부족 여부 확인
	if (true == NResource::Static::Instance().GetContentsOpenResource()->IsOpen(ContentsOpen::STAMINA_SYSTEM))
	{
		NLogic::Stamina * pStamina = pUser->GetStamina();
		if (NULL == pStamina)
		{
			DEBUGLOG("%s : pStamina is NULL", __FUNCTION__);
			SendFailDungeonCreatePartyFriendV2(pUser, ACK_UNKNOWN_ERROR);
			return;
		}

		if (true == pStamina->IsStaminaLack(difficulty))
		{
			SendFailDungeonCreatePartyFriendV2(pUser, ACK_NOT_ENOUGHT_DUNGEON_STAMINA);
			return;
		}
	}

	pWorld->LeaveUser(pUser);

	NLogic::Party * pParty = NLogic::Static::Instance().GETPARTYPOOL()->NEW();
	pParty->Open(pUser);
	pParty->SetState(NLogic::Party::State::INVITE);

	int staminaLackUserCount = 0;

	for (int i = 0; i < count; ++i)
	{
		int userSeq = 0;
		* pPacket >> userSeq;

		auto itr = NProxy::GetUserTree().find(userSeq);
		if (itr == NProxy::GetUserTree().end())
			continue;

		User * pTarget = itr->second;
		if (NULL == pTarget)
			continue;

		NLogic::Space * pSpaceTemp = pTarget->GetSpace();
		if (NULL == pSpaceTemp)
		{
			continue;
		}

		if (pTarget->GetEnumState() != User::EnumState::__NONE__)
			continue;

		NLogic::SocialInfo * pSocialInfo = pTarget->GetSocialInfo();
		if (NULL == pSocialInfo)
			continue;

		NLogic::SocialInfo::Data * pData = pSocialInfo->GetData();
		if (NULL == pData)
			continue;

		if (0 == (pData->_invite_blocked & static_cast<int>(NLogic::SocialInfo::EnumInviteState::DUNGEON_ON)))
			continue;

		// 초대 받은 친구의 스태미너 부족 여부 홧인
		if (true == NResource::Static::Instance().GetContentsOpenResource()->IsOpen(ContentsOpen::STAMINA_SYSTEM))
		{
			NLogic::Stamina * pStamina = pTarget->GetStamina();
			if (NULL != pStamina)
			{
				if (true == pStamina->IsStaminaLack(difficulty))
				{
					staminaLackUserCount++;
					continue;
				}
			}
		}

		pTarget->SetEnumState(User::EnumState::INVITE);
		pParty->EnterUser(pTarget);
		pParty->AddInviteUserTree(pTarget);
	}

	if (staminaLackUserCount >= count)
	{
		SendFailDungeonCreatePartyFriendV2(pUser, ACK_NOT_ENOUGHT_FRIEND_STAMINA);
		return;
	}

	if (pParty->GetInviteUserTree().size() <= 0)
	{
		SendFailDungeonCreatePartyFriendV2(pUser, ACK_DUNGEON_CREATE_PARTY_FRIEND_FAIL);
		return;
	}

	NLogic::Space::Data clsData;
	clsData._maxUser = static_cast<int>(count);
	clsData._table_id = dungeon_id;
	clsData._difficulty = difficulty;
	clsData._spaceType = NLogic::Space::SpaceType::PARTY_DUNGEION;

	NLogic::Space * pPartyDungeon = NLogic::Static::Instance().GETSPACEPOOL()->NEW();
	pPartyDungeon->Open(pUser, clsData);
	pPartyDungeon->SetParty(pParty);
	pPartyDungeon->EnterUser(pUser);

	pUser->GetBattle()->GetData()._combo_steak = 0;
	pUser->SetEnumState(User::EnumState::FRIEND_PARTY_WAIT);

	// 응답(OK)
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	*pAck << static_cast<int16_t>(ACK_OK);
	*pAck << static_cast<uint32_t>(pPartyDungeon->GetData()._index);
	pAck->MakePacket(CMD_SC_REQ_DUNGEON_CREATE_PARTY_FRIEND_V2);
	pUser->Send(pAck);
}

} /*NCommand*/ } /*ProjectZ*/
